package com.mhy.dexload;

import android.content.Context;
import android.util.Log;
import java.lang.reflect.Method;
import dalvik.system.DexClassLoader;

/**
 * Created By Mahongyin
 * Date    2021/2/26 11:32
 */
public class DexUtils {
    public static final String APP_DEX = "dex";

    private Context mContext;

    public DexUtils(Context context) {
        mContext = context;
    }

    public static final String TAG = "DexUtils";

    /**
     * @param filePath     dex 压缩文件路径 （可以是apk,jar,zip格式）    Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download";
     * @param classNameWithPackage 类在文件中位置 包名+类名  例如  android.util.Log
     *                             // ⭐️⭐️⭐️⭐️⭐️sd卡路径应为"/storage/emulated/0"，此处直接将文件拖入Genymotion，因此路径还需加上"/Download"
     *                             String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download";
     * @param methodParameType 方法参数类型 如 String.class  Boolean.TYPE
     * @param methodParame     方法需要传入的参数 如果无 可传(new Object[0])  如 new Object[]{"string",0,true}
     */
    public Object loadPlugin(String filePath, String classNameWithPackage, String methodName, Class<?>[] methodParameType, Object[] methodParame) {
        String dexOutPath = mContext.getDir(APP_DEX, Context.MODE_PRIVATE).getAbsolutePath();
//        new File(dexOutPath).mkdirs();
        DexClassLoader classLoader = new DexClassLoader(filePath, dexOutPath, null, mContext.getClassLoader());
        try {
            // 加载类 全名
            Class<?> mClass = classLoader.loadClass(classNameWithPackage);
            Method method = mClass.getMethod(methodName, methodParameType);//获取方法和参数类型
            method.setAccessible(true);
            //创建dynamic实例
            return method.invoke(mClass.newInstance(), methodParame);//调用参数 传参
        } catch (Exception e) {
            e.printStackTrace();
//            return e.getMessage();
        }
        return null;
    }

    /**
     * 打印系统的classLoader
     */
    private int i = 0;
    public void showClassLoader() {
        ClassLoader classLoader = mContext.getClassLoader();
        if (classLoader != null) {
            Log.i(TAG, "[classLoader] " + i + " : " + classLoader.toString());
            while (classLoader.getParent() != null) {
                classLoader = classLoader.getParent();
                Log.i(TAG, "[classLoader] " + i + " : " + classLoader.toString());
                i++;
            }
        }
    }

}
